/*
 * @Author: yanjikun
 * @Date: 2021-06-11 10:00:10
 * @LastEditors: yanjikun
 * @LastEditTime: 2022-06-13 15:21:37
 * @Description: file content
 */
import axios from 'axios'
import notification from 'ant-design-vue/es/notification'
import { message } from 'ant-design-vue'
import { AxiosError, AxiosRequestConfig, AxiosResponse, AxiosInstance } from 'axios'
import type { ICustomOptions, Result, YAxiosOption } from './types'
import { addPending } from './axiosCancel'
import { addLoading, removeLoading } from './axiosLoading'
import { HTTP_CODE } from '@/enums/httpEnums'
import { useUserStore } from '@/store/modules/user'

// 创建 axios 实例
const service: AxiosInstance = axios.create({
  baseURL: import.meta.env.VITE_APP_BASE_URL, // api base_url
  timeout: 60000, // 请求超时时间
})
/**
 * @description:axios自定义封装
 * @param {*} axiosConfig
 * @return {*} promise
 * @author: yanjikun
 */
export function YAxios<T = any>(
  axiosConfig: YAxiosOption,
  {
    dataStringify,
    requestCancel,
    fullLoading,
    errorMessage,
    allResponse,
    successMsg,
  }: ICustomOptions = {
    dataStringify: false,
    requestCancel: false,
    fullLoading: true,
    errorMessage: true,
    allResponse: false,
  },
): Promise<T> {
  const userStore = useUserStore()
  const config = {
    ...axiosConfig,
  }
  const err = (error: AxiosError) => {
    fullLoading && removeLoading()
    if (error.response) {
      const data = error.response.data as any
      const token = userStore.getToken()
      if (error.response.status === 403) {
        notification.error({
          message: 'Forbidden',
          description: data?.message,
        })
      }
      if (error.response.status === 401) {
        notification.error({
          message: 'Unauthorized',
          description: 'Authorization verification failed',
        })
        if (!token) {
          // store.dispatch('Logout').then(() => {
          //   setTimeout(() => {
          //     window.location.reload()
          //   }, 1500)
          // })
        }
      }
    }
    return Promise.reject(error)
  }

  if (dataStringify) {
    config.transformRequest = [
      (data: any) => {
        return toFormData(data)
      },
    ]
  }

  // request interceptor
  service.interceptors.request.use((config: AxiosRequestConfig): AxiosRequestConfig => {
    requestCancel && addPending(config)
    fullLoading && addLoading()
    const token = userStore.getToken()
    const Tenant = userStore.getTenant()
    if (token && Tenant) {
      const { headers } = config
      const customHeaders = {
        Authorization: token,
        Tenant,
      }
      config.headers = { ...headers, ...customHeaders }
    }
    return config
  }, err)
  // response interceptor
  service.interceptors.response.use((response: AxiosResponse<Result<T>>) => {
    fullLoading && removeLoading()
    return response
  }, err)
  return new Promise((resolve, reject) => {
    service(config)
      .then((res: AxiosResponse<Result<T>>) => {
        const { data, code, msg } = res.data
        if (code === HTTP_CODE.TIMEOUT) {
          userStore.logout()
          reject(msg)
          return
        }
        if (allResponse) {
          resolve(res as any)
        }

        if (code !== HTTP_CODE.SUCCESS) {
          errorMessage && message.error(msg)
          reject(msg)
        }
        successMsg && message.success(successMsg)
        resolve(data)
      })
      .catch((error) => {
        reject(error)
      })
  })
}

export const toFormData = (data: any) => {
  if (data === null) return null
  return Object.keys(data).reduce((formData, item) => {
    if (item === 'files') {
      //特殊判断若是内容为files数组，就让里面值不用走JSON.stringify
      data[item]?.forEach((curr: any) => {
        formData.append(item, curr.originFileObj)
      })
    } else {
      formData.append(item, data[item] ?? '')
    }
    return formData
  }, new FormData())
}
